# GNU GPL Version 3+ peg parser for llvm intermediate compiler format
# https://llvm.org/docs/LangRef.html
# notes:
# the format allows embedded 0x00 chars
# for newer versions of llvm this must be updated

%prefix "llvmir"

%source{

#include <stdio.h>

static const char *dbg_str[] = { "Evaluating rule", "Matched rule", "Abandoning rule" };

#define PCC_DEBUG(event, rule, level, pos, buffer, length) \
    fprintf(stdout, "%*s%s %s @%d [%.*s]\n", (int)(level * 2), "", dbg_str[event], rule, (int)pos, (int)length,  buffer); fflush(stdout)

    /* NOTE: To guarantee the output order, stderr, which can lead a race condition with stdout, is not used. */

}

llvmir	<- lines !.

lines <- ( comment / whitespace / TopLevelEntities )*

_ascii_letter_upper <- [A-Z]

_ascii_letter_lower <- [a-z]

_ascii_letter <- (_ascii_letter_upper / _ascii_letter_lower)

_letter <- (_ascii_letter / '$' / '-' / '.' / '_')

_escape_letter <- (_letter / '\\')

_decimal_digit <- [0-9]

_hex_digit <- (_decimal_digit / [A-F] / [a-f])

comment <- ';' (!endofline .)* endofline

whitespace <- ('\0' / ' ' / '\t' / endofline)+

endofline	<-	( '\r\n' / '\n' / '\r' / '\n\r' )+

_name <- _letter ( _letter / _decimal_digit )*

_escape_name <- _escape_letter ( _escape_letter / _decimal_digit )*

_quoted_name <- _quoted_string

_id <- _decimals

global_ident <- ( _global_name /  _global_id )

_global_name <- '@' ( _name / _quoted_name )

_global_id <- '@' _id

local_ident <- ( _local_name / _local_id )

_local_name <- '%' ( _name / _quoted_name )

_local_id <- '%' _id

label_ident <-
	( ( _letter / _decimal_digit ) ( _letter / _decimal_digit )* ':' )
	/  _quoted_string ':'

attr_group_id <- '#' _id

comdat_name <- '$' ( _name / _quoted_name )

metadata_name <- '!' _escape_name

metadata_id <- '!' _id

dwarf_tag <- 'D' 'W' '_' 'T' 'A' 'G' '_' ( _ascii_letter / _decimal_digit / '_' )+

dwarf_att_encoding <- 'D' 'W' '_' 'A' 'T' 'E' '_' ( _ascii_letter / _decimal_digit / '_' )+

di_flag <- 'D' 'I' 'F' 'l' 'a' 'g' ( _ascii_letter / _decimal_digit / '_' )+

dwarf_lang <- 'D' 'W' '_' 'L' 'A' 'N' 'G' '_' ( _ascii_letter / _decimal_digit / '_' )+

dwarf_cc <- 'D' 'W' '_' 'C' 'C' '_' ( _ascii_letter / _decimal_digit / '_' )+

checksum_kind <- 'C' 'S' 'K' '_' ( _ascii_letter / _decimal_digit / '_' )+

dwarf_virtuality <- 'D' 'W' '_' 'V' 'I' 'R' 'T' 'U' 'A' 'L' 'I' 'T' 'Y' '_' ( _ascii_letter / _decimal_digit / '_' )+

dwarf_macinfo <- 'D' 'W' '_' 'M' 'A' 'C' 'I' 'N' 'F' 'O' '_' ( _ascii_letter / _decimal_digit / '_' )+

dwarf_op <- 'D' 'W' '_' 'O' 'P' '_' ( _ascii_letter / _decimal_digit / '_' )+

int_lit <-  _decimal_lit

_decimal_lit <- ( '-' )?  _decimals

_decimals <- _decimal_digit ( _decimal_digit )*

float_lit <- ( _frac_lit / _sci_lit / _float_hex_lit )

_frac_lit <- (_sign )? _decimals '.' ( _decimal_digit )*

_sign <- ( '+' / '-' )

_sci_lit <-  _frac_lit ( 'e' / 'E' ) ( _sign )? _decimals

_float_hex_lit <-
	(  '0' 'x'      _hex_digit ( _hex_digit )+ )
	/ (  '0' 'x' 'K'  _hex_digit _hex_digit _hex_digit _hex_digit _hex_digit _hex_digit _hex_digit _hex_digit _hex_digit _hex_digit _hex_digit _hex_digit _hex_digit _hex_digit _hex_digit _hex_digit _hex_digit _hex_digit _hex_digit _hex_digit )
	/ (  '0' 'x' 'L'  _hex_digit _hex_digit _hex_digit _hex_digit _hex_digit _hex_digit _hex_digit _hex_digit _hex_digit _hex_digit _hex_digit _hex_digit _hex_digit _hex_digit _hex_digit _hex_digit _hex_digit _hex_digit _hex_digit _hex_digit _hex_digit _hex_digit _hex_digit _hex_digit _hex_digit _hex_digit _hex_digit _hex_digit _hex_digit _hex_digit _hex_digit _hex_digit )
	/ (  '0' 'x' 'M'  _hex_digit _hex_digit _hex_digit _hex_digit _hex_digit _hex_digit _hex_digit _hex_digit _hex_digit _hex_digit _hex_digit _hex_digit _hex_digit _hex_digit _hex_digit _hex_digit _hex_digit _hex_digit _hex_digit _hex_digit _hex_digit _hex_digit _hex_digit _hex_digit _hex_digit _hex_digit _hex_digit _hex_digit _hex_digit _hex_digit _hex_digit _hex_digit )
	/ (  '0' 'x' 'H'  _hex_digit _hex_digit _hex_digit _hex_digit )

string_lit <- _quoted_string

_quoted_string <-  '"' ( _quoted_stringchar )* '"'

_quoted_stringchar	<-
	'\\' "\""
	/ '\\' '\\'
	/ '\\' 'b'
	/ '\\' 'f'
	/ '\\' 'n'
	/ '\\' 'r'
	/ '\\' 't'
	/ (!"\"" .)

int_type <- 'i' _decimals


TopLevelEntities <- TopLevelEntityList

TopLevelEntityList <- TopLevelEntity
	/ TopLevelEntityList TopLevelEntity

TopLevelEntity <-  SourceFilename
 / TargetDefinition
 / ModuleAsm
 / TypeDef
 / ComdatDef
 / GlobalDecl
 / GlobalDef
 / IndirectSymbolDef
 / FunctionDecl
 / FunctionDef
 / AttrGroupDef
 / NamedMetadataDef
 / MetadataDef
 / UseListOrder
 / UseListOrderBB

SourceFilename <- "source_filename" "=" StringLit

TargetDefinition <- "target" "datalayout" "=" StringLit
 / "target" "triple" "=" StringLit

ModuleAsm <- "module" "asm" StringLit

TypeDef <- LocalIdent "=" "type" OpaqueType
 / LocalIdent "=" "type" Type

ComdatDef <- ComdatName "=" "comdat" SelectionKind

SelectionKind <- "any"
 / "exactmatch"
 / "largest"
 / "noduplicates"
 / "samesize"

GlobalDecl <- GlobalIdent "=" ExternLinkage ( OptPreemptionSpecifier )? ( OptVisibility )? ( OptDLLStorageClass )? ( OptThreadLocal )?  ( OptUnnamedAddr )? ( OptAddrSpace )? ( OptExternallyInitialized )? Immutable Type ( GlobalAttrs )? ( FuncAttrs )?

GlobalDef <- GlobalIdent "=" ( OptLinkage )? ( OptPreemptionSpecifier )? ( OptVisibility )? ( OptDLLStorageClass )? ( OptThreadLocal )? ( OptUnnamedAddr )? ( OptAddrSpace )? ( OptExternallyInitialized )? Immutable Type Constant ( GlobalAttrs )? ( FuncAttrs )?

OptExternallyInitialized <- "externally_initialized"

Immutable <- "constant"
 / "global"

GlobalAttrs <- GlobalAttrList

GlobalAttrList <- GlobalAttr
 / GlobalAttrList "," GlobalAttr

GlobalAttr <- Section
 / Comdat
 / Alignment
 / MetadataAttachment

IndirectSymbolDef <- GlobalIdent "=" ExternLinkage ( OptPreemptionSpecifier )? ( OptVisibility )? ( OptDLLStorageClass )? ( OptThreadLocal )? ( OptUnnamedAddr )? Alias Type "," Type Constant
 / GlobalIdent "=" ( OptLinkage )? ( OptPreemptionSpecifier )? ( OptVisibility )? ( OptDLLStorageClass )? ( OptThreadLocal )? ( OptUnnamedAddr )? Alias Type "," Type Constant

Alias <- "alias"
 / "ifunc"

FunctionDecl <- "declare" MetadataAttachments ( OptExternLinkage )? FunctionHeader

FunctionDef <- "define" ( OptLinkage )? FunctionHeader MetadataAttachments FunctionBody

FunctionHeader <- ( OptPreemptionSpecifier )? ( OptVisibility )? ( OptDLLStorageClass )? ( OptCallingConv )? ( ReturnAttrs )? Type GlobalIdent "(" ( Params )? ")" ( OptUnnamedAddr )?  ( FuncAttrs )? ( OptSection )? ( OptComdat )? ( OptGC )? ( OptPrefix )? ( OptPrologue )? ( OptPersonality )?

OptGC <-  "gc" StringLit

OptPrefix <- "prefix" Type Constant

OptPrologue <- "prologue" Type Constant

OptPersonality <- "personality" Type Constant

FunctionBody <- "{" BasicBlockList ( UseListOrders )? "}"

AttrGroupDef <- "attributes" AttrGroupID "=" "{" ( FuncAttrs )? "}"

NamedMetadataDef <- MetadataName "=" "!" "{" ( MetadataNodes )? "}"

MetadataNodes <- MetadataNodeList

MetadataNodeList <- MetadataNode
 / MetadataNodeList "," MetadataNode

MetadataNode <- MetadataID
 / DIExpression

MetadataDef <- MetadataID "=" ( OptDistinct )? MDTuple
 / MetadataID "=" ( OptDistinct )? SpecializedMDNode

OptDistinct <- "distinct"

UseListOrders <- UseListOrderList

UseListOrderList <- UseListOrder
 / UseListOrderList UseListOrder

UseListOrder <- "uselistorder" Type Value "," "{" IndexList "}"

UseListOrderBB <- "uselistorder_bb" GlobalIdent "," LocalIdent "," "{" IndexList "}"

GlobalIdent <- global_ident

LocalIdent <- local_ident

LabelIdent <- label_ident

AttrGroupID <- attr_group_id

ComdatName <- comdat_name

MetadataName <- metadata_name

MetadataID <- metadata_id

Type <- VoidType
 / FuncType
 / FirstClassType

FirstClassType <- ConcreteType
 / MetadataType

ConcreteType <- IntType
 / FloatType
 / PointerType
 / VectorType
 / LabelType
 / ArrayType
 / StructType
 / NamedType
 / MMXType
 / TokenType

VoidType <- "void"

FuncType <- Type "(" ( Params )? ")"

IntType <- int_type

FloatType <- FloatKind

FloatKind <- "half"
 / "float"
 / "double"
 / "x86_fp80"
 / "fp128"
 / "ppc_fp128"

MMXType <- "x86_mmx"

PointerType <- Type ( OptAddrSpace )? "*"

OptAddrSpace <- AddrSpace

AddrSpace <- "addrspace" "(" int_lit ")"

VectorType <- "<" int_lit "x" Type ">"

LabelType <- "label"

TokenType <- "token"

MetadataType <- "metadata"

ArrayType <- "[" int_lit "x" Type "]"

StructType <- "{" "}"
 / "{" TypeList "}"
 / "<" "{" "}" ">"
 / "<" "{" TypeList "}" ">"

TypeList <- Type
 / TypeList "," Type

OpaqueType <- "opaque"

NamedType <- LocalIdent

Value <- Constant
 / LocalIdent
 / InlineAsm

InlineAsm <- "asm" ( OptSideEffect )? ( OptAlignStack )? ( OptIntelDialect )? StringLit "," StringLit

OptSideEffect <- "sideeffect"

OptAlignStack <- "alignstack"

OptIntelDialect <- "inteldialect"

Constant <- BoolConst
 / IntConst
 / FloatConst
 / NullConst
 / NoneConst
 / StructConst
 / ArrayConst
 / CharArrayConst
 / VectorConst
 / ZeroInitializerConst
 / GlobalIdent
 / UndefConst
 / BlockAddressConst
 / ConstantExpr

BoolConst <- BoolLit

BoolLit <- ( "true" / "false" )

IntConst <- int_lit

IntLit <- int_lit

FloatConst <- float_lit

NullConst <- "null"

NoneConst <- "none"

StructConst <- "{" "}"
 / "{" TypeConstList "}"
 / "<" "{" "}" ">"
 / "<" "{" TypeConstList "}" ">"

ArrayConst <- "[" ( TypeConsts )? "]"

CharArrayConst <- "c" StringLit

StringLit <- string_lit

VectorConst <- "<" ( TypeConsts )? ">"

ZeroInitializerConst <- "zeroinitializer"

UndefConst <- "undef"

BlockAddressConst <- "blockaddress" "(" GlobalIdent "," LocalIdent ")"

ConstantExpr <- AddExpr
 / FAddExpr
 / SubExpr
 / FSubExpr
 / MulExpr
 / FMulExpr
 / UDivExpr
 / SDivExpr
 / FDivExpr
 / URemExpr
 / SRemExpr
 / FRemExpr
 / ShlExpr
 / LShrExpr
 / AShrExpr
 / AndExpr
 / OrExpr
 / XorExpr
 / ExtractElementExpr
 / InsertElementExpr
 / ShuffleVectorExpr
 / ExtractValueExpr
 / InsertValueExpr
 / GetElementPtrExpr
 / TruncExpr
 / ZExtExpr
 / SExtExpr
 / FPTruncExpr
 / FPExtExpr
 / FPToUIExpr
 / FPToSIExpr
 / UIToFPExpr
 / SIToFPExpr
 / PtrToIntExpr
 / IntToPtrExpr
 / BitCastExpr
 / AddrSpaceCastExpr
 / ICmpExpr
 / FCmpExpr
 / SelectExpr

AddExpr <- "add" ( OverflowFlags )? "(" Type Constant "," Type Constant ")"

FAddExpr <- "fadd" "(" Type Constant "," Type Constant ")"

SubExpr <- "sub" ( OverflowFlags )? "(" Type Constant "," Type Constant ")"

FSubExpr <- "fsub" "(" Type Constant "," Type Constant ")"

MulExpr <- "mul" ( OverflowFlags )? "(" Type Constant "," Type Constant ")"

FMulExpr <- "fmul" "(" Type Constant "," Type Constant ")"

UDivExpr <- "udiv" OptExact "(" Type Constant "," Type Constant ")"

SDivExpr <- "sdiv" OptExact "(" Type Constant "," Type Constant ")"

FDivExpr <- "fdiv" "(" Type Constant "," Type Constant ")"

URemExpr <- "urem" "(" Type Constant "," Type Constant ")"

SRemExpr <- "srem" "(" Type Constant "," Type Constant ")"

FRemExpr <- "frem" "(" Type Constant "," Type Constant ")"

ShlExpr <- "shl" ( OverflowFlags )? "(" Type Constant "," Type Constant ")"

LShrExpr <- "lshr" OptExact "(" Type Constant "," Type Constant ")"

AShrExpr <- "ashr" OptExact "(" Type Constant "," Type Constant ")"

AndExpr <- "and" "(" Type Constant "," Type Constant ")"

OrExpr <- "or" "(" Type Constant "," Type Constant ")"

XorExpr <- "xor" "(" Type Constant "," Type Constant ")"

ExtractElementExpr <- "extractelement" "(" Type Constant "," Type Constant ")"

InsertElementExpr <- "insertelement" "(" Type Constant "," Type Constant "," Type Constant ")"

ShuffleVectorExpr <- "shufflevector" "(" Type Constant "," Type Constant "," Type Constant ")"

ExtractValueExpr <- "extractvalue" "(" Type Constant ( Indices )? ")"

InsertValueExpr <- "insertvalue" "(" Type Constant "," Type Constant ( Indices )? ")"

GetElementPtrExpr <- "getelementptr" ( OptInBounds )? "(" Type "," Type Constant "," ( GEPConstIndices )? ")"

GEPConstIndices <- GEPConstIndexList

GEPConstIndexList <- GEPConstIndex
 / GEPConstIndexList "," GEPConstIndex

GEPConstIndex <- ( OptInrange )? Type Constant

OptInrange <- "inrange"

TruncExpr <- "trunc" "(" Type Constant "to" Type ")"

ZExtExpr <- "zext" "(" Type Constant "to" Type ")"

SExtExpr <- "sext" "(" Type Constant "to" Type ")"

FPTruncExpr <- "fptrunc" "(" Type Constant "to" Type ")"

FPExtExpr <- "fpext" "(" Type Constant "to" Type ")"

FPToUIExpr <- "fptoui" "(" Type Constant "to" Type ")"

FPToSIExpr <- "fptosi" "(" Type Constant "to" Type ")"

UIToFPExpr <- "uitofp" "(" Type Constant "to" Type ")"

SIToFPExpr <- "sitofp" "(" Type Constant "to" Type ")"

PtrToIntExpr <- "ptrtoint" "(" Type Constant "to" Type ")"

IntToPtrExpr <- "inttoptr" "(" Type Constant "to" Type ")"

BitCastExpr <- "bitcast" "(" Type Constant "to" Type ")"

AddrSpaceCastExpr <- "addrspacecast" "(" Type Constant "to" Type ")"

ICmpExpr <- "icmp" IPred "(" Type Constant "," Type Constant ")"

FCmpExpr <- "fcmp" FPred "(" Type Constant "," Type Constant ")"

SelectExpr <- "select" "(" Type Constant "," Type Constant "," Type Constant ")"

BasicBlockList <- BasicBlock
 / BasicBlockList BasicBlock

BasicBlock <- ( OptLabelIdent )? ( Instructions )? Terminator

OptLabelIdent <- LabelIdent

Instructions <- InstructionList

InstructionList <- Instruction
 / InstructionList Instruction

Instruction <- StoreInst
 / FenceInst
 / CmpXchgInst
 / AtomicRMWInst
 / LocalIdent "=" ValueInstruction
 / ValueInstruction

ValueInstruction <- AddInst
 / FAddInst
 / SubInst
 / FSubInst
 / MulInst
 / FMulInst
 / UDivInst
 / SDivInst
 / FDivInst
 / URemInst
 / SRemInst
 / FRemInst
 / ShlInst
 / LShrInst
 / AShrInst
 / AndInst
 / OrInst
 / XorInst
 / ExtractElementInst
 / InsertElementInst
 / ShuffleVectorInst
 / ExtractValueInst
 / InsertValueInst
 / AllocaInst
 / LoadInst
 / GetElementPtrInst
 / TruncInst
 / ZExtInst
 / SExtInst
 / FPTruncInst
 / FPExtInst
 / FPToUIInst
 / FPToSIInst
 / UIToFPInst
 / SIToFPInst
 / PtrToIntInst
 / IntToPtrInst
 / BitCastInst
 / AddrSpaceCastInst
 / ICmpInst
 / FCmpInst
 / PhiInst
 / SelectInst
 / CallInst
 / VAArgInst
 / LandingPadInst
 / CatchPadInst
 / CleanupPadInst

AddInst <- "add" ( OverflowFlags )? Type Value "," Value ( OptCommaSepMetadataAttachmentList )?

FAddInst <- "fadd" ( FastMathFlags )? Type Value "," Value ( OptCommaSepMetadataAttachmentList )?

SubInst <- "sub" ( OverflowFlags )? Type Value "," Value ( OptCommaSepMetadataAttachmentList )?

FSubInst <- "fsub" ( FastMathFlags )? Type Value "," Value ( OptCommaSepMetadataAttachmentList )?

MulInst <- "mul" ( OverflowFlags )? Type Value "," Value ( OptCommaSepMetadataAttachmentList )?

FMulInst <- "fmul" ( FastMathFlags )? Type Value "," Value ( OptCommaSepMetadataAttachmentList )?

UDivInst <- "udiv" OptExact Type Value "," Value ( OptCommaSepMetadataAttachmentList )?

SDivInst <- "sdiv" OptExact Type Value "," Value ( OptCommaSepMetadataAttachmentList )?

FDivInst <- "fdiv" ( FastMathFlags )? Type Value "," Value ( OptCommaSepMetadataAttachmentList )?

URemInst <- "urem" Type Value "," Value ( OptCommaSepMetadataAttachmentList )?

SRemInst <- "srem" Type Value "," Value ( OptCommaSepMetadataAttachmentList )?

FRemInst <- "frem" ( FastMathFlags )? Type Value "," Value ( OptCommaSepMetadataAttachmentList )?

ShlInst <- "shl" ( OverflowFlags )? Type Value "," Value ( OptCommaSepMetadataAttachmentList )?

LShrInst <- "lshr" OptExact Type Value "," Value ( OptCommaSepMetadataAttachmentList )?

AShrInst <- "ashr" OptExact Type Value "," Value ( OptCommaSepMetadataAttachmentList )?

AndInst <- "and" Type Value "," Value ( OptCommaSepMetadataAttachmentList )?

OrInst <- "or" Type Value "," Value ( OptCommaSepMetadataAttachmentList )?

XorInst <- "xor" Type Value "," Value ( OptCommaSepMetadataAttachmentList )?

ExtractElementInst <- "extractelement" Type Value "," Type Value ( OptCommaSepMetadataAttachmentList )?

InsertElementInst <- "insertelement" Type Value "," Type Value "," Type Value ( OptCommaSepMetadataAttachmentList )?

ShuffleVectorInst <- "shufflevector" Type Value "," Type Value "," Type Value ( OptCommaSepMetadataAttachmentList )?

ExtractValueInst <- "extractvalue" Type Value "," IndexList ( OptCommaSepMetadataAttachmentList )?

InsertValueInst <- "insertvalue" Type Value "," Type Value "," IndexList ( OptCommaSepMetadataAttachmentList )?

AllocaInst <- "alloca" ( OptInAlloca )? ( OptSwiftError )? Type ( OptCommaSepMetadataAttachmentList )?
 / "alloca" ( OptInAlloca )? ( OptSwiftError )? Type "," Alignment ( OptCommaSepMetadataAttachmentList )?
 / "alloca" ( OptInAlloca )? ( OptSwiftError )? Type "," Type Value ( OptCommaSepMetadataAttachmentList )?
 / "alloca" ( OptInAlloca )? ( OptSwiftError )? Type "," Type Value "," Alignment ( OptCommaSepMetadataAttachmentList )?
 / "alloca" ( OptInAlloca )? ( OptSwiftError )? Type "," AddrSpace ( OptCommaSepMetadataAttachmentList )?
 / "alloca" ( OptInAlloca )? ( OptSwiftError )? Type "," Alignment "," AddrSpace ( OptCommaSepMetadataAttachmentList )?
 / "alloca" ( OptInAlloca )? ( OptSwiftError )? Type "," Type Value "," AddrSpace ( OptCommaSepMetadataAttachmentList )?
 / "alloca" ( OptInAlloca )? ( OptSwiftError )? Type "," Type Value "," Alignment "," AddrSpace ( OptCommaSepMetadataAttachmentList )?

OptInAlloca <- "inalloca"

OptSwiftError <- "swifterror"

LoadInst <- "load" ( OptVolatile )? Type "," Type Value ( OptCommaSepMetadataAttachmentList )?
 / "load" ( OptVolatile )? Type "," Type Value "," Alignment ( OptCommaSepMetadataAttachmentList )?
 / "load" "atomic" ( OptVolatile )? Type "," Type Value ( OptSyncScope )? AtomicOrdering ( OptCommaSepMetadataAttachmentList )?
 / "load" "atomic" ( OptVolatile )? Type "," Type Value ( OptSyncScope )? AtomicOrdering "," Alignment ( OptCommaSepMetadataAttachmentList )?

StoreInst <- "store" ( OptVolatile )? Type Value "," Type Value ( OptCommaSepMetadataAttachmentList )?
 / "store" ( OptVolatile )? Type Value "," Type Value "," Alignment ( OptCommaSepMetadataAttachmentList )?
 / "store" "atomic" ( OptVolatile )? Type Value "," Type Value ( OptSyncScope )? AtomicOrdering ( OptCommaSepMetadataAttachmentList )?
 / "store" "atomic" ( OptVolatile )? Type Value "," Type Value ( OptSyncScope )? AtomicOrdering "," Alignment ( OptCommaSepMetadataAttachmentList )?

FenceInst <- "fence" ( OptSyncScope )? AtomicOrdering ( OptCommaSepMetadataAttachmentList )?

CmpXchgInst <- "cmpxchg" ( OptWeak )? ( OptVolatile )? Type Value "," Type Value "," Type Value ( OptSyncScope )? AtomicOrdering AtomicOrdering ( OptCommaSepMetadataAttachmentList )?

OptWeak <- "weak"

AtomicRMWInst <- "atomicrmw" ( OptVolatile )? BinOp Type Value "," Type Value ( OptSyncScope )? AtomicOrdering ( OptCommaSepMetadataAttachmentList )?

BinOp <- "add"
 / "and"
 / "max"
 / "min"
 / "nand"
 / "or"
 / "sub"
 / "umax"
 / "umin"
 / "xchg"
 / "xor"

GetElementPtrInst <- "getelementptr" ( OptInBounds )? Type "," Type Value ( OptCommaSepMetadataAttachmentList )?
 / "getelementptr" ( OptInBounds )? Type "," Type Value "," CommaSepTypeValueList ( OptCommaSepMetadataAttachmentList )?

TruncInst <- "trunc" Type Value "to" Type ( OptCommaSepMetadataAttachmentList )?

ZExtInst <- "zext" Type Value "to" Type ( OptCommaSepMetadataAttachmentList )?

SExtInst <- "sext" Type Value "to" Type ( OptCommaSepMetadataAttachmentList )?

FPTruncInst <- "fptrunc" Type Value "to" Type ( OptCommaSepMetadataAttachmentList )?

FPExtInst <- "fpext" Type Value "to" Type ( OptCommaSepMetadataAttachmentList )?

FPToUIInst <- "fptoui" Type Value "to" Type ( OptCommaSepMetadataAttachmentList )?

FPToSIInst <- "fptosi" Type Value "to" Type ( OptCommaSepMetadataAttachmentList )?

UIToFPInst <- "uitofp" Type Value "to" Type ( OptCommaSepMetadataAttachmentList )?

SIToFPInst <- "sitofp" Type Value "to" Type ( OptCommaSepMetadataAttachmentList )?

PtrToIntInst <- "ptrtoint" Type Value "to" Type ( OptCommaSepMetadataAttachmentList )?

IntToPtrInst <- "inttoptr" Type Value "to" Type ( OptCommaSepMetadataAttachmentList )?

BitCastInst <- "bitcast" Type Value "to" Type ( OptCommaSepMetadataAttachmentList )?

AddrSpaceCastInst <- "addrspacecast" Type Value "to" Type ( OptCommaSepMetadataAttachmentList )?

ICmpInst <- "icmp" IPred Type Value "," Value ( OptCommaSepMetadataAttachmentList )?

FCmpInst <- "fcmp" ( FastMathFlags )? FPred Type Value "," Value ( OptCommaSepMetadataAttachmentList )?

PhiInst <- "phi" Type IncList ( OptCommaSepMetadataAttachmentList )?

IncList <- Inc
 / IncList "," Inc

Inc <- "[" Value "," LocalIdent "]"

SelectInst <- "select" Type Value "," Type Value "," Type Value ( OptCommaSepMetadataAttachmentList )?

CallInst <- ( OptTail )? "call" ( FastMathFlags )? ( OptCallingConv )? ( ReturnAttrs )? Type Value "(" ( Args )? ")" ( FuncAttrs )? ( OperandBundles )? ( OptCommaSepMetadataAttachmentList )?

OptTail <- "musttail"
 / "notail"
 / "tail"

VAArgInst <- "va_arg" Type Value "," Type ( OptCommaSepMetadataAttachmentList )?

LandingPadInst <- "landingpad" Type ( OptCleanup )? ( Clauses )? ( OptCommaSepMetadataAttachmentList )?

OptCleanup <- "cleanup"

Clauses <- ClauseList

ClauseList <- Clause
 / ClauseList Clause

Clause <- "catch" Type Value
 / "filter" Type ArrayConst

CatchPadInst <- "catchpad" "within" LocalIdent "[" ( ExceptionArgs )? "]" ( OptCommaSepMetadataAttachmentList )?

CleanupPadInst <- "cleanuppad" "within" ExceptionScope "[" ( ExceptionArgs )? "]" ( OptCommaSepMetadataAttachmentList )?

Terminator <- RetTerm
 / BrTerm
 / CondBrTerm
 / SwitchTerm
 / IndirectBrTerm
 / InvokeTerm
 / ResumeTerm
 / CatchSwitchTerm
 / CatchRetTerm
 / CleanupRetTerm
 / UnreachableTerm

RetTerm <- "ret" VoidType ( OptCommaSepMetadataAttachmentList )?
 / "ret" ConcreteType Value ( OptCommaSepMetadataAttachmentList )?

BrTerm <- "br" LabelType LocalIdent ( OptCommaSepMetadataAttachmentList )?

CondBrTerm <- "br" IntType Value "," LabelType LocalIdent "," LabelType LocalIdent ( OptCommaSepMetadataAttachmentList )?

SwitchTerm <- "switch" Type Value "," LabelType LocalIdent "[" ( Cases )? "]" ( OptCommaSepMetadataAttachmentList )?

Cases <- CaseList

CaseList <- Case
 / CaseList Case

Case <- Type IntConst "," LabelType LocalIdent

IndirectBrTerm <- "indirectbr" Type Value "," "[" LabelList "]" ( OptCommaSepMetadataAttachmentList )?

LabelList <- Label
 / LabelList "," Label

Label <- LabelType LocalIdent

InvokeTerm <- "invoke" ( OptCallingConv )? ( ReturnAttrs )? Type Value "(" ( Args )? ")" ( FuncAttrs )?  ( OperandBundles )? "to" LabelType LocalIdent "unwind" LabelType LocalIdent ( OptCommaSepMetadataAttachmentList )?

ResumeTerm <- "resume" Type Value ( OptCommaSepMetadataAttachmentList )?

CatchSwitchTerm <- "catchswitch" "within" ExceptionScope "[" LabelList "]" "unwind" UnwindTarget ( OptCommaSepMetadataAttachmentList )?

CatchRetTerm <- "catchret" "from" Value "to" LabelType LocalIdent ( OptCommaSepMetadataAttachmentList )?

CleanupRetTerm <- "cleanupret" "from" Value "unwind" UnwindTarget ( OptCommaSepMetadataAttachmentList )?

UnreachableTerm <- "unreachable" ( OptCommaSepMetadataAttachmentList )?

UnwindTarget <- "to" "caller"
 / LabelType LocalIdent

MDTuple <- "!" MDFields

MDFields <- "{" "}"
 / "{" MDFieldList "}"

MDFieldList <- MDField
 / MDFieldList "," MDField

MDField <- "null"
 / Metadata

Metadata <- Type Value
 / MDString
 / MDTuple
 / MetadataID
 / SpecializedMDNode

MDString <- "!" StringLit

MetadataAttachment <- MetadataName MDNode

MDNode <- MDTuple
 / MetadataID
 / SpecializedMDNode

MetadataAttachments <- MetadataAttachmentList

MetadataAttachmentList <- MetadataAttachment
 / MetadataAttachmentList MetadataAttachment

OptCommaSepMetadataAttachmentList <- "," CommaSepMetadataAttachmentList

CommaSepMetadataAttachmentList <- MetadataAttachment
 / CommaSepMetadataAttachmentList "," MetadataAttachment

SpecializedMDNode <- DICompileUnit
 / DIFile
 / DIBasicType
 / DISubroutineType
 / DIDerivedType
 / DICompositeType
 / DISubrange
 / DIEnumerator
 / DITemplateTypeParameter
 / DITemplateValueParameter
 / DIModule
 / DINamespace
 / DIGlobalVariable
 / DISubprogram
 / DILexicalBlock
 / DILexicalBlockFile
 / DILocation
 / DILocalVariable
 / DIExpression
 / DIGlobalVariableExpression
 / DIObjCProperty
 / DIImportedEntity
 / DIMacro
 / DIMacroFile
 / GenericDINode

DICompileUnit <- "!DICompileUnit" "(" ( DICompileUnitFields )? ")"

DICompileUnitFields <- DICompileUnitFieldList

DICompileUnitFieldList <- DICompileUnitField
 / DICompileUnitFieldList "," DICompileUnitField

DICompileUnitField <- "language:" DwarfLang
 / FileField
 / "producer:" StringLit
 / IsOptimizedField
 / "flags:" StringLit
 / "runtimeVersion:" IntLit
 / "splitDebugFilename:" StringLit
 / "emissionKind:" EmissionKind
 / "enums:" MDField
 / "retainedTypes:" MDField
 / "globals:" MDField
 / "imports:" MDField
 / "macros:" MDField
 / "dwoId:" IntLit
 / "splitDebugInlining:" BoolLit
 / "debugInfoForProfiling:" BoolLit
 / "gnuPubnames:" BoolLit

DIFile <- "!DIFile" "(" ( DIFileFields )? ")"

DIFileFields <- DIFileFieldList

DIFileFieldList <- DIFileField
 / DIFileFieldList "," DIFileField

DIFileField <- "filename:" StringLit
 / "directory:" StringLit
 / "checksumkind:" ChecksumKind
 / "checksum:" StringLit

DIBasicType <- "!DIBasicType" "(" ( DIBasicTypeFields )? ")"

DIBasicTypeFields <- DIBasicTypeFieldList

DIBasicTypeFieldList <- DIBasicTypeField
 / DIBasicTypeFieldList "," DIBasicTypeField

DIBasicTypeField <- TagField
 / NameField
 / SizeField
 / AlignField
 / "encoding:" DwarfAttEncoding

DISubroutineType <- "!DISubroutineType" "(" ( DISubroutineTypeFields )? ")"

DISubroutineTypeFields <- DISubroutineTypeFieldList

DISubroutineTypeFieldList <- DISubroutineTypeField
 / DISubroutineTypeFieldList "," DISubroutineTypeField

DISubroutineTypeField <- FlagsField
 / "cc:" DwarfCC
 / "types:" MDField

DIDerivedType <- "!DIDerivedType" "(" ( DIDerivedTypeFields )? ")"

DIDerivedTypeFields <- DIDerivedTypeFieldList

DIDerivedTypeFieldList <- DIDerivedTypeField
 / DIDerivedTypeFieldList "," DIDerivedTypeField

DIDerivedTypeField <- TagField
 / NameField
 / ScopeField
 / FileField
 / LineField
 / BaseTypeField
 / SizeField
 / AlignField
 / OffsetField
 / FlagsField
 / "extraData:" MDField
 / "dwarfAddressSpace:" IntLit

DICompositeType <- "!DICompositeType" "(" ( DICompositeTypeFields )? ")"

DICompositeTypeFields <- DICompositeTypeFieldList

DICompositeTypeFieldList <- DICompositeTypeField
 / DICompositeTypeFieldList "," DICompositeTypeField

DICompositeTypeField <- TagField
 / NameField
 / ScopeField
 / FileField
 / LineField
 / BaseTypeField
 / SizeField
 / AlignField
 / OffsetField
 / FlagsField
 / "elements:" MDField
 / "runtimeLang:" DwarfLang
 / "vtableHolder:" MDField
 / TemplateParamsField
 / "identifier:" StringLit
 / "discriminator:" MDField

DISubrange <- "!DISubrange" "(" ( DISubrangeFields )? ")"

DISubrangeFields <- DISubrangeFieldList

DISubrangeFieldList <- DISubrangeField
 / DISubrangeFieldList "," DISubrangeField

DISubrangeField <- "count:" IntOrMDField
 "lowerBound:" IntLit

DIEnumerator <- "!DIEnumerator" "(" ( DIEnumeratorFields )? ")"

DIEnumeratorFields <- DIEnumeratorFieldList

DIEnumeratorFieldList <- DIEnumeratorField
 / DIEnumeratorFieldList "," DIEnumeratorField

DIEnumeratorField <- NameField
 / "value:" IntLit
 / "isUnsigned:" BoolLit

DITemplateTypeParameter <- "!DITemplateTypeParameter" "(" ( DITemplateTypeParameterFields )? ")"

DITemplateTypeParameterFields <- DITemplateTypeParameterFieldList

DITemplateTypeParameterFieldList <- DITemplateTypeParameterField
 / DITemplateTypeParameterFieldList "," DITemplateTypeParameterField

DITemplateTypeParameterField <- NameField
 / TypeField

DITemplateValueParameter <- "!DITemplateValueParameter" "(" ( DITemplateValueParameterFields )? ")"

DITemplateValueParameterFields <- DITemplateValueParameterFieldList

DITemplateValueParameterFieldList <- DITemplateValueParameterField
 / DITemplateValueParameterFieldList "," DITemplateValueParameterField

DITemplateValueParameterField <- TagField
 / NameField
 / TypeField
 / "value:" MDField

DIModule <- "!DIModule" "(" ( DIModuleFields )? ")"

DIModuleFields <- DIModuleFieldList

DIModuleFieldList <- DIModuleField
 / DIModuleFieldList "," DIModuleField

DIModuleField <- ScopeField
 / NameField
 / "configMacros:" StringLit
 / "includePath:" StringLit
 / "isysroot:" StringLit

DINamespace <- "!DINamespace" "(" ( DINamespaceFields )? ")"

DINamespaceFields <- DINamespaceFieldList

DINamespaceFieldList <- DINamespaceField
 / DINamespaceFieldList "," DINamespaceField

DINamespaceField <- ScopeField
 / NameField
 / "exportSymbols:" BoolLit

DIGlobalVariable <- "!DIGlobalVariable" "(" ( DIGlobalVariableFields )? ")"

DIGlobalVariableFields <- DIGlobalVariableFieldList

DIGlobalVariableFieldList <- DIGlobalVariableField
 / DIGlobalVariableFieldList "," DIGlobalVariableField

DIGlobalVariableField <- NameField
 / ScopeField
 / LinkageNameField
 / FileField
 / LineField
 / TypeField
 / IsLocalField
 / IsDefinitionField
 / DeclarationField
 / AlignField

DISubprogram <- "!DISubprogram" "(" ( DISubprogramFields )? ")"

DISubprogramFields <- DISubprogramFieldList

DISubprogramFieldList <- DISubprogramField
 / DISubprogramFieldList "," DISubprogramField

DISubprogramField <- NameField
 / ScopeField
 / LinkageNameField
 / FileField
 / LineField
 / TypeField
 / IsLocalField
 / IsDefinitionField
 / "scopeLine:" IntLit
 / "containingType:" MDField
 / "virtuality:" DwarfVirtuality
 / "virtualIndex:" IntLit
 / "thisAdjustment:" IntLit
 / FlagsField
 / IsOptimizedField
 / "unit:" MDField
 / TemplateParamsField
 / DeclarationField
 / "variables:" MDField
 / "thrownTypes:" MDField

DILexicalBlock <- "!DILexicalBlock" "(" ( DILexicalBlockFields )? ")"

DILexicalBlockFields <- DILexicalBlockFieldList

DILexicalBlockFieldList <- DILexicalBlockField
 / DILexicalBlockFieldList "," DILexicalBlockField

DILexicalBlockField <- ScopeField
 / FileField
 / LineField
 / ColumnField

DILexicalBlockFile <- "!DILexicalBlockFile" "(" ( DILexicalBlockFileFields )? ")"

DILexicalBlockFileFields <- DILexicalBlockFileFieldList

DILexicalBlockFileFieldList <- DILexicalBlockFileField
 / DILexicalBlockFileFieldList "," DILexicalBlockFileField

DILexicalBlockFileField <- ScopeField
 / FileField
 / "discriminator:" IntLit

DILocation <- "!DILocation" "(" ( DILocationFields )? ")"

DILocationFields <- DILocationFieldList

DILocationFieldList <- DILocationField
 / DILocationFieldList "," DILocationField

DILocationField <- LineField
 / ColumnField
 / ScopeField
 / "inlinedAt:" MDField

DILocalVariable <- "!DILocalVariable" "(" ( DILocalVariableFields )? ")"

DILocalVariableFields  <- DILocalVariableFieldList

DILocalVariableFieldList <- DILocalVariableField
 / DILocalVariableFieldList "," DILocalVariableField

DILocalVariableField <- NameField
 / "arg:" IntLit
 / ScopeField
 / FileField
 / LineField
 / TypeField
 / FlagsField
 / AlignField

DIExpression <- "!DIExpression" "(" ( DIExpressionFields )? ")"

DIExpressionFields <- DIExpressionFieldList

DIExpressionFieldList <- DIExpressionField
 / DIExpressionFieldList "," DIExpressionField

DIExpressionField <- int_lit
 / DwarfOp

DIGlobalVariableExpression <- "!DIGlobalVariableExpression" "(" ( DIGlobalVariableExpressionFields )? ")"

DIGlobalVariableExpressionFields <- DIGlobalVariableExpressionFieldList

DIGlobalVariableExpressionFieldList <- DIGlobalVariableExpressionField
 / DIGlobalVariableExpressionFieldList "," DIGlobalVariableExpressionField

DIGlobalVariableExpressionField <- "var:" MDField
 / "expr:" MDField

DIObjCProperty <- "!DIObjCProperty" "(" ( DIObjCPropertyFields )? ")"

DIObjCPropertyFields <- DIObjCPropertyFieldList

DIObjCPropertyFieldList <- DIObjCPropertyField
 / DIObjCPropertyFieldList "," DIObjCPropertyField

DIObjCPropertyField <- NameField
 / FileField
 / LineField
 / "setter:" StringLit
 / "getter:" StringLit
 / "attributes:" IntLit
 / TypeField

DIImportedEntity <- "!DIImportedEntity" "(" ( DIImportedEntityFields )? ")"

DIImportedEntityFields <- DIImportedEntityFieldList

DIImportedEntityFieldList <- DIImportedEntityField
 / DIImportedEntityFieldList "," DIImportedEntityField

DIImportedEntityField <- TagField
 / ScopeField
 / "entity:" MDField
 / FileField
 / LineField
 / NameField

DIMacro <- "!DIMacro" "(" ( DIMacroFields )? ")"

DIMacroFields <- DIMacroFieldList

DIMacroFieldList <- DIMacroField
 / DIMacroFieldList "," DIMacroField

DIMacroField <- TypeMacinfoField
 / LineField
 / NameField
 / "value:" StringLit

DIMacroFile <- "!DIMacroFile" "(" ( DIMacroFileFields )? ")"

DIMacroFileFields <- DIMacroFileFieldList

DIMacroFileFieldList <- DIMacroFileField
 / DIMacroFileFieldList "," DIMacroFileField

DIMacroFileField <- TypeMacinfoField
 / LineField
 / FileField
 / "nodes:" MDField

GenericDINode <- "!GenericDINode" "(" ( GenericDINodeFields )? ")"

GenericDINodeFields <- GenericDINodeFieldList

GenericDINodeFieldList <- GenericDINodeField
 / GenericDINodeFieldList "," GenericDINodeField

GenericDINodeField <- TagField
 / "header:" StringLit
 / "operands:" MDFields

FileField <- "file:" MDField

IsOptimizedField <- "isOptimized:" BoolLit

TagField <- "tag:" DwarfTag

NameField <- "name:" StringLit

SizeField <- "size:" IntLit

AlignField <- "align:" IntLit

FlagsField <- "flags:" DIFlagList

LineField <- "line:" IntLit

ScopeField <- "scope:" MDField

BaseTypeField <- "baseType:" MDField

OffsetField <- "offset:" IntLit

TemplateParamsField <- "templateParams:" MDField

IntOrMDField <- int_lit
 / MDField

TypeField <- "type:" MDField

LinkageNameField <- "linkageName:" StringLit

IsLocalField <- "isLocal:" BoolLit

IsDefinitionField <- "isDefinition:" BoolLit

DeclarationField <- "declaration:" MDField

ColumnField <- "column:" IntLit

TypeMacinfoField <- "type:" DwarfMacinfo

ChecksumKind <- checksum_kind

DIFlagList <- DIFlag
 / DIFlagList "|" DIFlag

DIFlag <- IntLit
 / di_flag

DwarfAttEncoding <- IntLit
 / dwarf_att_encoding

DwarfCC <- IntLit
 / dwarf_cc

DwarfLang <- IntLit
 / dwarf_lang

DwarfMacinfo <- IntLit
 / dwarf_macinfo

DwarfOp <- dwarf_op

DwarfTag <- IntLit
 / dwarf_tag

DwarfVirtuality <- IntLit
 / dwarf_virtuality

EmissionKind <- IntLit
 / "FullDebug"
 / "LineTablesOnly"
 / "NoDebug"

TypeValues <- TypeValueList

TypeValueList <- TypeValue
 / TypeValueList TypeValue

CommaSepTypeValueList <- TypeValue
 / CommaSepTypeValueList "," TypeValue

TypeValue <- Type Value

TypeConsts <- TypeConstList

TypeConstList <- TypeConst
 / TypeConstList "," TypeConst

TypeConst <- Type Constant

Alignment <- "align" int_lit

AllocSize <- "allocsize" "(" int_lit ")"
 / "allocsize" "(" int_lit "," int_lit ")"

Args <- "..."
 / ArgList
 / ArgList "," "..."

ArgList <- Arg
 / ArgList "," Arg

Arg <- ConcreteType ( ParamAttrs )? Value
 / MetadataType Metadata

AtomicOrdering <- "acq_rel"
 / "acquire"
 / "monotonic"
 / "release"
 / "seq_cst"
 / "unordered"

OptCallingConv <- CallingConv

CallingConv <- "amdgpu_cs"
 / "amdgpu_es"
 / "amdgpu_gs"
 / "amdgpu_hs"
 / "amdgpu_kernel"
 / "amdgpu_ls"
 / "amdgpu_ps"
 / "amdgpu_vs"
 / "anyregcc"
 / "arm_aapcs_vfpcc"
 / "arm_aapcscc"
 / "arm_apcscc"
 / "avr_intrcc"
 / "avr_signalcc"
 / "ccc"
 / "coldcc"
 / "cxx_fast_tlscc"
 / "fastcc"
 / "ghccc"
 / "hhvm_ccc"
 / "hhvmcc"
 / "intel_ocl_bicc"
 / "msp430_intrcc"
 / "preserve_allcc"
 / "preserve_mostcc"
 / "ptx_device"
 / "ptx_kernel"
 / "spir_func"
 / "spir_kernel"
 / "swiftcc"
 / "webkit_jscc"
 / "win64cc"
 / "x86_64_sysvcc"
 / "x86_fastcallcc"
 / "x86_intrcc"
 / "x86_regcallcc"
 / "x86_stdcallcc"
 / "x86_thiscallcc"
 / "x86_vectorcallcc"
 / "cc" int_lit

OptComdat <- Comdat

Comdat <- "comdat"
 / "comdat" "(" ComdatName ")"

Dereferenceable <- "dereferenceable" "(" int_lit ")"
 / "dereferenceable_or_null" "(" int_lit ")"

OptDLLStorageClass <- DLLStorageClass

DLLStorageClass <- "dllexport"
 / "dllimport"

OptExact <- "exact"

ExceptionArgs <- ExceptionArgList

ExceptionArgList <- ExceptionArg
 / ExceptionArgList "," ExceptionArg

ExceptionArg <- ConcreteType Value
 / MetadataType Metadata

ExceptionScope <- NoneConst
 / LocalIdent

FastMathFlags <- FastMathFlagList

FastMathFlagList <- FastMathFlag
 / FastMathFlagList FastMathFlag

FastMathFlag <- "afn"
 / "arcp"
 / "contract"
 / "fast"
 / "ninf"
 / "nnan"
 / "nsz"
 / "reassoc"

FPred <- "false"
 / "oeq"
 / "oge"
 / "ogt"
 / "ole"
 / "olt"
 / "one"
 / "ord"
 / "true"
 / "ueq"
 / "uge"
 / "ugt"
 / "ule"
 / "ult"
 / "une"
 / "uno"

FuncAttrs <- FuncAttrList

FuncAttrList <- FuncAttr
 / FuncAttrList FuncAttr

FuncAttr <- AttrGroupID
 / "align" "=" int_lit
 / "alignstack" "=" int_lit
 / Alignment
 / AllocSize
 / StackAlignment
 / StringLit
 / StringLit "=" StringLit
 / "alwaysinline"
 / "argmemonly"
 / "builtin"
 / "cold"
 / "convergent"
 / "inaccessiblemem_or_argmemonly"
 / "inaccessiblememonly"
 / "inlinehint"
 / "jumptable"
 / "minsize"
 / "naked"
 / "nobuiltin"
 / "noduplicate"
 / "noimplicitfloat"
 / "noinline"
 / "nonlazybind"
 / "norecurse"
 / "noredzone"
 / "noreturn"
 / "nounwind"
 / "optnone"
 / "optsize"
 / "readnone"
 / "readonly"
 / "returns_twice"
 / "safestack"
 / "sanitize_address"
 / "sanitize_hwaddress"
 / "sanitize_memory"
 / "sanitize_thread"
 / "speculatable"
 / "ssp"
 / "sspreq"
 / "sspstrong"
 / "strictfp"
 / "uwtable"
 / "writeonly"

OptInBounds <- "inbounds"

Indices <-"," IndexList

IndexList <- Index
 / IndexList "," Index

Index <- int_lit

IPred <- "eq"
 / "ne"
 / "sge"
 / "sgt"
 / "sle"
 / "slt"
 / "uge"
 / "ugt"
 / "ule"
 / "ult"

OptLinkage <- Linkage

Linkage <- "appending"
 / "available_externally"
 / "common"
 / "internal"
 / "linkonce"
 / "linkonce_odr"
 / "private"
 / "weak"
 / "weak_odr"

OptExternLinkage <- ExternLinkage

ExternLinkage <- "extern_weak"
 / "external"

OperandBundles <- "[" OperandBundleList "]"

OperandBundleList <- OperandBundle
 / OperandBundleList OperandBundle

OperandBundle <- StringLit "(" ( TypeValues )? ")"

OverflowFlags <- OverflowFlagList

OverflowFlagList <- OverflowFlag
 / OverflowFlagList OverflowFlag

OverflowFlag <- "nsw"
 / "nuw"

ParamAttrs <- ParamAttrList

ParamAttrList <- ParamAttr
 / ParamAttrList ParamAttr

ParamAttr <- Alignment
 / Dereferenceable
 / StringLit
 / "byval"
 / "inalloca"
 / "inreg"
 / "nest"
 / "noalias"
 / "nocapture"
 / "nonnull"
 / "readnone"
 / "readonly"
 / "returned"
 / "signext"
 / "sret"
 / "swifterror"
 / "swiftself"
 / "writeonly"
 / "zeroext"

Params <- "..."
 / ParamList
 / ParamList "," "..."

ParamList <- Param
 / ParamList "," Param

Param <- Type ParamAttrs
 / Type ParamAttrs LocalIdent

OptPreemptionSpecifier <- PreemptionSpecifier

PreemptionSpecifier <- "dso_local"
 / "dso_preemptable"

ReturnAttrs <- ReturnAttrList

ReturnAttrList <- ReturnAttr
 / ReturnAttrList ReturnAttr

ReturnAttr <- Alignment
 / Dereferenceable
 / StringLit
 / "inreg"
 / "noalias"
 / "nonnull"
 / "signext"
 / "zeroext"

OptSection <- Section

Section <- "section" StringLit

StackAlignment <- "alignstack" "(" int_lit ")"

OptSyncScope <- "syncscope" "(" StringLit ")"

OptThreadLocal <- ThreadLocal

ThreadLocal <- "thread_local"
 / "thread_local" "(" TLSModel ")"

TLSModel <- "initialexec"
 / "localdynamic"
 / "localexec"

OptUnnamedAddr <- UnnamedAddr

UnnamedAddr <- "local_unnamed_addr"
 / "unnamed_addr"

OptVisibility <- Visibility

Visibility <- "default"
 / "hidden"
 / "protected"

OptVolatile <- "volatile"

%%

int main() {
    llvmir_context_t *ctx=llvmir_create(NULL);
    while (llvmir_parse(ctx, NULL)){;}
    llvmir_destroy(ctx);
    return 0;
}

